package cn.com.yiqi.wsc.service.order.impl;

import cn.com.artemis.framework.service.message.service.yunxin.impl.YunxinSMSServiceImpl;
import cn.com.yiqi.wsc.Ro.PortalOrderRefundVO;
import cn.com.yiqi.wsc.common.Result;
import cn.com.yiqi.wsc.common.ResultStatusEnum;
import cn.com.yiqi.wsc.common.ResultUtil;
import cn.com.yiqi.wsc.dao.city.CityDao;
import cn.com.yiqi.wsc.dao.customer.CustomerMapper;
import cn.com.yiqi.wsc.dao.order.*;
import cn.com.yiqi.wsc.dao.order.criteria.OrderCriteria;
import cn.com.yiqi.wsc.dao.order.criteria.OrderRefundCriteria;
import cn.com.yiqi.wsc.entity.order.*;
import cn.com.yiqi.wsc.enumeration.KdniaoStates;
import cn.com.yiqi.wsc.ro.KdniaoRO;
import cn.com.yiqi.wsc.service.balance.BalanceService;
import cn.com.yiqi.wsc.service.balance.dataobject.BalanceRecordDO;
import cn.com.yiqi.wsc.service.balance.enumeration.BalanceType;
import cn.com.yiqi.wsc.service.balance.enumeration.OperateType;
import cn.com.yiqi.wsc.service.kdniao.KdniaoTrackQueryAPI;
import cn.com.yiqi.wsc.service.order.PortalOrderService;
import cn.com.yiqi.wsc.service.order.enumeration.OrderRefundStatus;
import cn.com.yiqi.wsc.service.order.enumeration.OrderStatus;
import cn.com.yiqi.wsc.service.order.enumeration.OrderSubStatus;
import cn.com.yiqi.wsc.service.user.UserService;
import cn.com.yiqi.wsc.util.KdniaoUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @author 何刚
 * @ClassName: ${class}
 * @Description: TODO
 * @date 2017/3/14
 */
@Service
public class PortalOrderServiceImpl implements PortalOrderService {

    @Autowired
    private OrderMainDao orderMainDao;

    @Autowired
    private OrderSubMapper orderSubMapper;

    @Autowired
    private OrderPayDao orderPayDao;

    @Autowired
    private OrderLogisticsDao orderLogisticsDao;

    @Autowired
    private OrderRefundDao orderRefundDao;

    @Autowired
    private OrderRefundLogDao orderRefundLogDao;

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private KdniaoTrackQueryAPI kdniaoTrackQueryAPI;

    @Autowired
    private UserService userService;

    @Autowired
    private YunxinSMSServiceImpl yunxinSMSService;

    @Autowired
    private BalanceService balanceService;

    @Autowired
    private CityDao cityDao;

    @Value("#{APP_PROP['yunxin.sms.org.templateId']}")
    private Integer templateId;

    @Override
    public Result pageList(OrderCriteria criteria) {

        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());

        PageHelper.startPage(criteria.getCurrentPage(), criteria.getPageSize());

        PageHelper.orderBy("mom.d_insert_time,mom.n_id DESC");
        PageInfo<OrderMainDTO> pageInfo = new PageInfo<>(orderMainDao.pageList(criteria));

        result.putData("list", pageInfo.getList());
        result.putData("total", pageInfo.getTotal());

        return result;
    }

    @Override
    public Result detail(OrderCriteria criteria) {

        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());

        OrderMainDTO orderMainDTO = orderMainDao.getOrderBaseInfo(criteria);

        if (orderMainDTO != null) {
            String address = cityDao.getNameByCode(orderMainDTO.getCityCode());
            orderMainDTO.setAddress(address);
        }

        result.putData("detail", orderMainDTO);
        OrderCriteria subOrderCriteria = new OrderCriteria();
        subOrderCriteria.setPid(criteria.getId());
        subOrderCriteria.setPageSize(Integer.MAX_VALUE);
        subOrderCriteria.setCurrentPage(1);
        result.putData("orderList", orderMainDao.pageList(subOrderCriteria));

        return result;
    }

    public Result orderItems(Long orderId) {
        Result result = new Result();
        List<OrderSub> orderSubList = orderSubMapper.getOrderItems(orderId);
        result.setReturnValue(orderSubList);
        return result;
    }

    @Override
    public Result refundLogList(Long refundId) {
        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());
        List<OrderRefundLog> list = orderRefundLogDao.findLogList(refundId);
        result.setReturnValue(list);
        return result;
    }

    @Override
    public Result notifyOrg(Integer orderId) {

        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());

        String tel = orderMainDao.getOrgTelByOrderId(orderId.longValue());

        if (tel != null) {

            if (!yunxinSMSService.sendTemplate(templateId, "[" + tel + "]", null)) {
                return ResultUtil.paramError(result, "发送短信失败");
            }

        } else {
            return ResultUtil.paramError(result, "商家未填写联系电话");
        }


        return result;
    }

    @Override
    public Result payDetail(OrderCriteria criteria) {
        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());

        result.putData("payDetail", orderPayDao.getOrderPayDetailByOrderId(criteria.getId()));

        return result;
    }

    @Override
    public Result shipLogisticsDetail(OrderCriteria criteria) {
        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());

        OrderMainDTO orderMainDTO = orderMainDao.getOrderBaseInfo(criteria);
        if (null == orderMainDTO) {
            result.setStatus(ResultStatusEnum.参数错误.getCode());
            result.setErrMsg("订单不存在");
            return result;
        }
        List<Long> subIdList = null;
        Integer orderId = criteria.getId();
        if (orderMainDTO.getPid() == 0) {
            subIdList = orderMainDao.getSubIdList(criteria.getId().longValue());
            orderId = null;
        }

        //查询订单详情
        List<OrderLogistics> logisticsList = orderLogisticsDao.getOrderLogisticsByOrderId(orderId, subIdList);
        result.putData("shipLogisticsDetail", logisticsList);

        //查询订单跟踪信息
        for (OrderLogistics ol :
                logisticsList) {
            String traces = null;
            traces = ol.getTraces();
            if (ol != null && StringUtils.isEmpty(traces)) {
                //如果没有订单跟踪信息
                String companyCode = ol.getLogisticsCompanyCode();
                String trackingNo = ol.getLogisticsTrackingNo();

                try {
                    KdniaoRO kdniaoRO = KdniaoUtil.json2Obj(kdniaoTrackQueryAPI.getOrderTracesByJson(companyCode, trackingNo));

                    if (kdniaoRO.isSuccess()) {

                        traces = JSON.toJSONString(kdniaoRO.getTraces());
                        if (KdniaoStates.签收.getState().equals(kdniaoRO.getState())) {
                            //如果订单已签收
                            //修改跟踪记录

                            OrderLogistics orderLogisticsForUpdate = new OrderLogistics();
                            orderLogisticsForUpdate.setId(ol.getId());
                            orderLogisticsForUpdate.setTraces(traces);

                            orderLogisticsDao.update(orderLogisticsForUpdate);

                        }

                        ol.setTraces(traces);

                    }
                } catch (Exception e) {
                    result.setStatus(ResultStatusEnum.服务器内部错误.getCode());
                    result.setErrMsg("获取订单跟踪信息失败");
                }

            }
        }

        return result;
    }

    @Transactional
    @Override
    public Result insertLogistics(OrderLogistics orderLogistics) {
        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());

        OrderCriteria orderCriteria = new OrderCriteria();
        orderCriteria.setId(orderLogistics.getOrderId());
        OrderMainDTO orderMainDTO = orderMainDao.getOrderBaseInfo(orderCriteria);
        if (null == orderMainDTO) {
            result.setStatus(ResultStatusEnum.参数错误.getCode());
            result.setErrMsg("订单不存在");
            return result;
        }

        orderLogistics.setInsertTime(new Date());
        if (orderLogisticsDao.insert(orderLogistics) > 0) {
            //更新订单状态
            Integer pid = orderMainDTO.getPid();
            if (null == pid) {
                result.setStatus(ResultStatusEnum.参数错误.getCode());
                result.setErrMsg("订单不存在");
                return result;
            }

            OrderCriteria subOrderCriteria = new OrderCriteria();
            subOrderCriteria.setPid(pid);
            subOrderCriteria.setStatus(OrderStatus.wait_to_send.getValue() + "");
            List<OrderMainDTO> subOrderList = orderMainDao.pageList(subOrderCriteria);

            OrderMain orderMain = new OrderMain();
            if (subOrderList.size() == 1) {
                orderMain.setId(pid);
                orderMain.setStatus(OrderStatus.wait_to_get.getValue().byteValue());
                if (orderMainDao.update(orderMain) <= 0) {
                    result.setStatus(ResultStatusEnum.服务器内部错误.getCode());
                    result.setErrMsg("系统错误");
                    return result;
                }
            }
            orderMain = new OrderMain();
            orderMain.setId(orderLogistics.getOrderId());
            orderMain.setStatus(OrderStatus.wait_to_get.getValue().byteValue());
            if (orderMainDao.update(orderMain) > 0) {
                /*if (orderSubMapper.updateStatus(orderLogistics.getOrderId().longValue(), OrderStatus.wait_to_get.getValue()) > 0) {
                    return result;
                } else {
                    result.setStatus(ResultStatusEnum.服务器内部错误.getCode());
                    result.setErrMsg("系统错误");
                    return result;
                }*/
                return result;
            } else {
                result.setStatus(ResultStatusEnum.服务器内部错误.getCode());
                result.setErrMsg("系统错误");
                return result;
            }
        } else {
            result.setStatus(ResultStatusEnum.服务器内部错误.getCode());
            result.setErrMsg("系统错误");
            return result;
        }
    }

    @Override
    public Result refundPageList(OrderRefundCriteria criteria) {


        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());


        PageHelper.startPage(criteria.getCurrentPage(), criteria.getPageSize());

        if (StringUtils.isNotEmpty(criteria.getOrderBy())) {
            PageHelper.orderBy(criteria.getOrderBy());
        }

        PageInfo<PortalOrderRefundVO> pageInfo = new PageInfo<>(orderRefundDao.pageList(criteria));

        result.putData("list", pageInfo.getList());
        result.putData("total", pageInfo.getTotal());

        return result;
    }

    @Transactional
    @Override
    public Result refundCheckOrg(OrderRefundLog orderRefundLog) {

        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());

        Integer userId = userService.getCurrentUserId();
        orderRefundLog.setInsertTime(new Date());
        orderRefundLog.setOperateTime(new Date());
        orderRefundLog.setOperatorId(userId);
        orderRefundLog.setInsertUserId(userId);
        orderRefundLogDao.insert(orderRefundLog);

        Integer orderRefundId = orderRefundLog.getRefundId();
        OrderRefund orderRefund = new OrderRefund();
        orderRefund.setId(orderRefundId);
        orderRefund.setUpdateUserId(orderRefund.getInsertUserId());
        if (orderRefundLog.getResult() == 1) {
            orderRefund.setStatus(OrderRefundStatus.finance_check.getValue());
        } else {
            orderRefund.setStatus(OrderRefundStatus.reject.getValue());
            updateStatus(orderRefundId);
        }
        orderRefundDao.update(orderRefund);


        return result;
    }

    @Transactional
    @Override
    public Result refundCheckFinance(OrderRefundLog orderRefundLog) {
        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());

        Integer userId = userService.getCurrentUserId();

        orderRefundLog.setInsertTime(new Date());
        orderRefundLog.setOperateTime(new Date());
        orderRefundLog.setOperatorId(userId);
        orderRefundLog.setInsertUserId(userId);
        orderRefundLogDao.insert(orderRefundLog);

        Integer orderRefundId = orderRefundLog.getRefundId();
        OrderRefund orderRefund = new OrderRefund();
        orderRefund.setId(orderRefundId);
        orderRefund.setUpdateUserId(orderRefund.getInsertUserId());
        if (orderRefundLog.getResult() == 1) {
            orderRefund.setStatus(OrderRefundStatus.operator_check.getValue());
        } else {
            orderRefund.setStatus(OrderRefundStatus.reject.getValue());

            updateStatus(orderRefundId);


        }
        orderRefundDao.update(orderRefund);


        return result;
    }

    private void updateStatus(Integer orderRefundId) {
        OrderRefund orderRefund1 = new OrderRefund();
        orderRefund1.setId(orderRefundId);
        orderRefund1 = orderRefundDao.get(orderRefund1);
        Integer orderId = orderRefund1.getOrderSubId();

        //修改子订单表状态
        orderSubMapper.changeStatus(orderId, OrderSubStatus.reject.getValue());


    }

    @Transactional
    @Override
    public Result refundConfirm(OrderRefund orderRefund) {
        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());


        Integer userId = userService.getCurrentUserId();
        orderRefund.setStatus(OrderRefundStatus.completed.getValue());
        orderRefund.setOperatorId(userId);
//        orderRefund.setInsertUserId(userId);
        orderRefund.setCompleteTime(new Date());
        orderRefundDao.update(orderRefund);

        orderRefund = orderRefundDao.getRefundAmount(orderRefund);


        if (orderRefund != null) {
            BalanceRecordDO balanceRecordDO = new BalanceRecordDO();
            balanceRecordDO.setDesc("订单退款");
            balanceRecordDO.setCustomerId(orderRefund.getCustomerId().longValue());
            balanceRecordDO.setAmount(orderRefund.getRefundAmount());
            balanceRecordDO.setType(BalanceType.refund);

            //balanceRecordDO.
/*            record.setDesc(bdo.getDesc());
            record.setCustomerId(bdo.getCustomerId());
            record.setOperateTime(new Date());

            record.setOperateType(OperateType.ADD.getValue());
            record.setAmount(bdo.getAmount());
            record.setType(bdo.getType().getValue());*/
            //添加余额
            balanceService.getBalance(balanceRecordDO);


            OrderRefund orderRefund1 = new OrderRefund();
            orderRefund1.setId(orderRefund.getId());
            orderRefund1 = orderRefundDao.get(orderRefund1);
            Integer orderSubId = orderRefund1.getOrderSubId();

            OrderSub orderSub = orderSubMapper.selectByPrimaryKey(orderSubId);

            Integer orderId = orderSub.getOrderId();
            //修改子订单表状态
            orderSubMapper.updateStatus(orderId.longValue(), OrderSubStatus.refund.getValue());
            //修改修改订单表状态
            OrderMain orderMain = new OrderMain();
            orderMain.setId(orderId);
            orderMain.setStatus(OrderStatus.cancel.getValue().byteValue());
            orderMainDao.update(orderMain);


            OrderCriteria orderCriteria = new OrderCriteria();
            orderCriteria.setId(orderId);

            OrderMainDTO orderMainDTO = orderMainDao.getOrderBaseInfo(orderCriteria);


            //修改主订单状态 1.判断是否所有子订单都已经是退货状态了。
            if (orderMainDao.countOrderSubStatus(orderId, OrderStatus.cancel.getValue()) == 0) {
                //如果所有子订单订单全部都取消，
                //修改所有单状态
                OrderMain orderMain1 = new OrderMain();
                orderMain1.setId(orderMainDTO.getPid());
                orderMain1.setStatus(OrderStatus.cancel.getValue().byteValue());
                orderMainDao.update(orderMain1);

            }

        }
        return result;
    }

    @Transactional
    @Override
    public Result refundCheckOperator(OrderRefundLog orderRefundLog) {
        Result result = new Result();
        result.setStatus(ResultStatusEnum.操作成功.getCode());

        Integer userId = userService.getCurrentUserId();
        orderRefundLog.setInsertTime(new Date());
        orderRefundLog.setOperateTime(new Date());
        orderRefundLog.setOperatorId(userId);
        orderRefundLog.setInsertUserId(userId);

        orderRefundLogDao.insert(orderRefundLog);

        Integer orderRefundId = orderRefundLog.getRefundId();
        OrderRefund orderRefund = new OrderRefund();
        orderRefund.setId(orderRefundId);
        orderRefund.setUpdateUserId(orderRefund.getInsertUserId());
        if (orderRefundLog.getResult() == 1) {
            orderRefund.setStatus(OrderRefundStatus.confirm_refund.getValue());
        } else {
            orderRefund.setStatus(OrderRefundStatus.reject.getValue());
            updateStatus(orderRefundId);
        }

        orderRefundDao.update(orderRefund);


        return result;
    }


}
